#pragma once
/*
 *  SBJ/NXT/Output.h
 *  NXTFace
 *
 *  Created by David Giovannini on 8/23/06.
 *  Copyright 2006 Software by Jove. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 */

#include "SBJ/NXT/Enums.h"
#include "SBJ/NXT/Types.h"
#include "SBJ/NXT/CommandTraits.h"

#include <iostream>

namespace SBJ
{

namespace NXT
{

class Device;

enum MotorUnit
{
	motorUnit_degrees = 1
};

class Output
{
public:
	typedef GetOutput::Results Snapshot;
	
// Construction
	Output( Device& device, OutputPort id );
	
	~Output( void );
	
// Accessors
	OutputPort getPort( bool refresh = false );
	
	const Snapshot& getSnapshot( void ) const { return m_snapshot; }
	
	SBytes1 getPower( bool refresh = true );
	bool getMotorMode( MotorMode mode, bool refresh = true ); 
	bool getRegulation( Regulation regulation, bool refresh = true );
	SBytes1 getTurnRatio( bool refresh = true );
	bool getMotorState( MotorState state, bool refresh = true );
	UBytes4 getTachoLimit( bool refresh = true );
	
	bool isInMotion( bool refresh = true );
	SBytes4 getTachoCount( bool refresh = true );
	SBytes4 getBlockTachoCount( bool refresh = true );
	SBytes4 getRotateTachoCount( bool refresh = true );
	
// Manipulators
	void setPower( SBytes1 power, bool query = true, Synchonous syncType = sync );
	void setMotorMode( MotorMode add, MotorMode remove = mode_none, bool query = true, Synchonous syncType = sync );
	void setRegulation( Regulation add, Regulation remove = regulation_idle, bool query = true, Synchonous syncType = sync );
	void setTurnRatio( SBytes1 turnRation, bool query = true, Synchonous syncType = sync );
	void setMotorState( MotorState add, MotorState remove, bool query = true, Synchonous syncType = sync );
	void setTachoLimit( UBytes4 tachoLimit, bool query = true, Synchonous syncType = sync );

// Commands
	void start( SBytes1 power, bool query = true, Synchonous syncType = sync );
	void stop( bool useBrake = true, bool query = true, Synchonous syncType = sync );
	void start( SBytes1 power, double duration, MotorUnit unit = motorUnit_degrees, bool useBrake = true, bool query = true, Synchonous syncType = sync );
	void resetSensor( bool relative );

private:
	void set( Synchonous syncType );
	void get( void );

	Device& m_device;
	Snapshot m_snapshot;
};

void
print( Output& output, std::ostream& str );

}

}